package com.think.cloud.thinkshop.mall.service.shippingtemplates.impl;

import com.think.cloud.thinkshop.common.enums.shippingtemplates.ChargingTypeEnum;
import com.think.cloud.thinkshop.mall.domain.shippingtemplates.ShippingTemplates;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class ShippingCalculator {

    // 按件数计算运费
    public static BigDecimal calculateByItemCount(int itemCount, BigDecimal firstItemCount, BigDecimal firstItemFee, BigDecimal additionalItemCount, BigDecimal additionalItemFee) {
        if (itemCount <= firstItemCount.intValue()) {
            return firstItemFee.setScale(2, RoundingMode.HALF_UP); // 保留两位小数并四舍五入
        } else {
            int additionalItems = (int) Math.ceil((itemCount - firstItemCount.intValue()) / additionalItemCount.intValue());
            BigDecimal additionalFee = additionalItemCount.multiply(new BigDecimal(additionalItems))
                    .multiply(additionalItemFee).setScale(2, RoundingMode.HALF_UP);
            return firstItemFee.add(additionalFee);
        }
    }

    // 按重量计算运费
    public static BigDecimal calculateByWeight(BigDecimal weight, BigDecimal firstWeight, BigDecimal firstWeightFee, BigDecimal additionalWeight, BigDecimal additionalWeightFee) {
        if (weight.compareTo(firstWeight) <= 0) {
            return firstWeightFee.setScale(2, RoundingMode.HALF_UP); // 保留两位小数并四舍五入
        } else {
            int additionalWeights = (int) Math.ceil((weight.subtract(firstWeight)).divide(additionalWeight, 0, RoundingMode.CEILING).doubleValue());
            BigDecimal additionalFee = additionalWeightFee.multiply(new BigDecimal(additionalWeights))
                    .setScale(2, RoundingMode.HALF_UP);
            return firstWeightFee.add(additionalFee);
        }
    }

    // 固定运费
    public static BigDecimal calculateFixedFee(BigDecimal fixedFee) {
        return fixedFee.setScale(2, RoundingMode.HALF_UP); // 即使是固定费用，也确保保留两位小数并四舍五入
    }

    public static void main(String[] args) {
        // 示例计算
        BigDecimal itemCountFee = calculateByItemCount(25, new BigDecimal("10"), new BigDecimal("10.00"), new BigDecimal("5"), new BigDecimal("2.00"));
        BigDecimal weightFee = calculateByWeight(new BigDecimal("12.5"), new BigDecimal("5"), new BigDecimal("5.00"), new BigDecimal("1"), new BigDecimal("1.50"));
        BigDecimal fixedFee = calculateFixedFee(new BigDecimal("15.00"));

        System.out.println("按件数计算的运费: " + itemCountFee);
        System.out.println("按重量计算的运费: " + weightFee);
        System.out.println("固定运费: " + fixedFee);
    }


    /**
     * 根据订单金额、订单物品数量、重量和运输模板计算运费。
     * @param orderAmount 订单总金额，
     * @param orderItemCount 订单中的物品数量。
     * @param weight 订单的总重量
     * @param templates 运输模板，包含运费计算所需的各种参数。
     * @return 计算出的运费
     */
    public static BigDecimal calculate(BigDecimal orderAmount, int orderItemCount, BigDecimal weight, ShippingTemplates templates) {
        //判断是否免运费
        if (templates.getEnableFree() && orderAmount.compareTo(templates.getOrderAmount()) > 0 && templates.getOrderItemCount() > orderItemCount) {
            return BigDecimal.ZERO;
        }
        if (templates.getChargingType() == ChargingTypeEnum.BY_ITEM_COUNT.getCode()) {
            return ShippingCalculator.calculateByItemCount(orderItemCount, templates.getFirstPiece(), templates.getFirstPrice(), templates.getOtherPiece(), templates.getOtherPrice());
        } else if (templates.getChargingType() == ChargingTypeEnum.BY_WEIGHT.getCode()) {
            return ShippingCalculator.calculateByWeight(weight, templates.getFirstPiece(), templates.getFirstPrice(), templates.getOtherPiece(), templates.getOtherPrice());
        } else if (templates.getChargingType() == ChargingTypeEnum.FIXED_FEE.getCode()) {
            return ShippingCalculator.calculateFixedFee(templates.getFixedPrice());
        }
        return BigDecimal.ZERO;
    }
}
